package com.xinjian.jianba.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.xinjian.jianba.dao.dwmart.MeetDistanceDao;
import com.xinjian.jianba.dao.dwmart.MeetDuraDao;
import com.xinjian.jianba.dao.dwmart.MeetTimeDao;
import com.xinjian.jianba.dao.dwmid.BuziInfoDao;
import com.xinjian.jianba.dao.dwmid.FirstLocationDao;
import com.xinjian.jianba.dao.dwmid.UserInfoDao;
import com.xinjian.jianba.dao.dwmid.UserLableDao;
import com.xinjian.jianba.dao.dwmid.UserLocationDao;
import com.xinjian.jianba.dao.dwmid.UserLocationHDao;
import com.xinjian.jianba.dao.dwmid.UserMediaDao;
import com.xinjian.jianba.dao.dwmid.UserRelationDao;
import com.xinjian.jianba.dao.dwmid.UserSignDao;
import com.xinjian.jianba.dto.CheckCodeDto;
import com.xinjian.jianba.dto.DetailedUserInfoDto;
import com.xinjian.jianba.dto.ForgetPasswordDto;
import com.xinjian.jianba.dto.IndexDto;
import com.xinjian.jianba.dto.IndexInfoDto;
import com.xinjian.jianba.dto.LableTreeDto;
import com.xinjian.jianba.dto.LoginDto;
import com.xinjian.jianba.dto.LoginVo;
import com.xinjian.jianba.dto.PasswordUpdateDto;
import com.xinjian.jianba.dto.RegisterLocationVo;
import com.xinjian.jianba.dto.RegisterUserDto;
import com.xinjian.jianba.dto.RongYunDto;
import com.xinjian.jianba.dto.UserInfoDto;
import com.xinjian.jianba.dto.UserInfoVo;
import com.xinjian.jianba.dto.UserMessageVo;
import com.xinjian.jianba.dto.geo.GeoResult;
import com.xinjian.jianba.dto.geo.Results;
import com.xinjian.jianba.enity.BuziInfoEntity;
import com.xinjian.jianba.enity.FirstLocationEnity;
import com.xinjian.jianba.enity.MeetDistanceEnity;
import com.xinjian.jianba.enity.MeetDuraEnity;
import com.xinjian.jianba.enity.MeetTimeEnity;
import com.xinjian.jianba.enity.UserInfoEnity;
import com.xinjian.jianba.enity.UserLableEnity;
import com.xinjian.jianba.enity.UserLocationEnity;
import com.xinjian.jianba.enity.UserRelationEntity;
import com.xinjian.jianba.enity.UserSignEnity;
import com.xinjian.jianba.exception.BusinessException;
import com.xinjian.jianba.exception.Page;
import com.xinjian.jianba.exception.Pageable;
import com.xinjian.jianba.exception.ResponseCode;
import com.xinjian.jianba.service.LableService;
import com.xinjian.jianba.service.ProcedureService;
import com.xinjian.jianba.service.RedisService;
import com.xinjian.jianba.service.SmsService;
import com.xinjian.jianba.service.UserService;
import com.xinjian.jianba.utils.Constants;
import com.xinjian.jianba.utils.DateUtil;
import com.xinjian.jianba.utils.JianBaEnum;
import com.xinjian.jianba.utils.JsonUtil;
import com.xinjian.jianba.utils.ListUtil;
import com.xinjian.jianba.utils.MD5Util;
import com.xinjian.jianba.utils.RongYunUtil;
import com.xinjian.jianba.utils.Utils;

/**
 * 用户service
 *
 */
/**
 * @author 10649
 *
 */
/**
 * @author 10649
 *
 */
@Service
public class UserServiceImpl implements UserService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

	private final static String buziname="xxx";
	
	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private UserMediaDao userMediaDao;
	@Autowired
	private UserLocationDao userLocationDao;
	@Autowired
	private UserLableDao userLableDao;
	@Autowired
	private UserSignDao userSignDao;
	
	@Autowired
	private BuziInfoDao buziInfoDao;

	@Autowired
	private UserRelationDao userRelationDao;

	@Autowired
	private MeetDistanceDao meetDistanceDao;

	@Autowired
	private MeetDuraDao meetDuraDao;

	@Autowired
	private UserInfoDao UserInfoDao;

	@Autowired
	private MeetTimeDao meetTimeDao;
	@Autowired
	private UserLocationHDao userLocationHDao;

	@Autowired
	private RedisService redisService;

	@Autowired
	private ProcedureService procedureService;

	@Autowired
	private FirstLocationDao firstLocationDao;

	@Autowired
	private LableService lableService;

	@Autowired
	private SmsService smsService;
	
	@Value("${jianba.vod.imgStr}")
	private String imgStr;
	@Value("${spring.near.geo.near.distance}")
	private double nearDistance;

	@Value("${spring.near.geo.near.count}")
	private int nearCount;

	@Value("${spring.meet.geo.db}")
	private String meetDb;

	@Value("${spring.meet.geo.male.db}")
	private String maleMeetDb;

	@Value("${spring.meet.geo.female.db}")
	private String femaleMeetDb;


	@Value("${jianba.qiniu.female}")
	private String female;

	@Value("${jianba.qiniu.male}")
	private String male;

	@Value("${jianba.business.buziLogo}")
	private String buziLogo;
	/**
	 * 注册
	 * @throws Exception 
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, Object> register(RegisterUserDto dto) throws Exception {
		//校验验证码
		CheckCodeDto checkCodeDto=new CheckCodeDto();
		checkCodeDto.setCode(dto.getCheckCode());
		checkCodeDto.setMobile(dto.getMobile());
		checkCodeDto.setType(0);
		smsService.checkCode(checkCodeDto);
		//
		Integer isRegister;
		UserInfoEnity userInfo = new UserInfoEnity();
		userInfo.setMobile(dto.getMobile());
		userInfo.setSex(null);
		userInfo.setUsrStatus(JianBaEnum.UserStatusEnum.NORMAL.getValue());
		List<UserInfoEnity> isExist = userInfoDao.select(userInfo);
		if (!CollectionUtils.isEmpty(isExist)) {
			isRegister = ((UserInfoEnity) isExist.get(0)).getIs_register();
			Long userId = ((UserInfoEnity) isExist.get(0)).getId();
			if (isRegister == 0) {
				userInfo.setUsrPassword(MD5Util.MD5(dto.getPassword().trim()));
				userInfo.setLngfloat(dto.getLngfloat());
				userInfo.setLatfloat(dto.getLatfloat());
				userInfo.setCreTime(new Date());
				userInfo.setUpdTime(new Date());
				userInfo.setId(userId);
				userInfoDao.update(userInfo);
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("id", userId);
				map.put("token", ((UserInfoEnity) isExist.get(0)).getPushToken());
				return map;

			} else if (isRegister == 1) {
				throw new BusinessException(ResponseCode.ERROR, "该用户已经注册,请登录!");
			}
		}
		userInfo.setUuid(dto.getUuid());
		userInfo.setUsrPassword(MD5Util.MD5(dto.getPassword().trim()));
		userInfo.setSource(dto.getSource());
		userInfo.setLngfloat(dto.getLngfloat());
		userInfo.setLatfloat(dto.getLatfloat());
		userInfo.setCreTime(new Date());
		userInfo.setUpdTime(new Date());
		userInfo.setIs_register(0);
		String token = MD5Util.MD5(Utils.generateUUID());
		userInfo.setPushToken(token);
		int line = userInfoDao.insert(userInfo);
		LOGGER.info("----user----register----------" + line);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", userInfo.getId());
		map.put("token", token);
		return map;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public LoginVo login(LoginDto loginDto) throws Exception {
		UserInfoEnity userInfo = new UserInfoEnity();
		userInfo.setMobile(loginDto.getMobile());
		userInfo.setUsrName(loginDto.getUsrName());
		userInfo.setUsrPassword(MD5Util.MD5(loginDto.getPassword().trim()));
		userInfo.setIs_register(1);
		List<UserInfoEnity> isRegist = userInfoDao.select(userInfo);
		if (CollectionUtils.isEmpty(isRegist)) {
			throw new BusinessException(ResponseCode.ERROR, "账号密码错误!");
		}
		String userId = null;
		String nickName = null;
		String headAdress = null;

		LoginVo vo = new LoginVo();
		if (!CollectionUtils.isEmpty(isRegist)) {
			UserInfoEnity user = isRegist.get(0);
			userId = String.valueOf(user.getId());
			nickName = user.getNickname();
			headAdress = user.getUserLogo();
			Integer userStatus = user.getUsrStatus();
			if (!userStatus.equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
				throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
			}

			UserInfoEnity usertokenInfo = new UserInfoEnity();
			usertokenInfo.setId(user.getId());
			usertokenInfo.setPushToken(MD5Util.MD5(Utils.generateUUID()));
			usertokenInfo.setUpdTime(new Date());
			int line = userInfoDao.update(usertokenInfo);
			LOGGER.info("----user----PushToken----------" + line);
			vo.setId(user.getId());
			vo.setToken(usertokenInfo.getPushToken());
			vo.setSex(user.getSex());
			vo.setNickname(nickName);
			vo.setUserLogo(headAdress);
			vo.setMeetType(userInfo.getMeetType()==null?"0":(userInfo.getMeetType()+""));
			if (null == user.getBirthday()) {
				vo.setBirthday("1991-01-01");
			} else {
				vo.setBirthday(DateUtil.format(user.getBirthday(), "yyyy-MM-dd"));
			}
		}
		String RongYunToken = RongYunUtil.getRongYunToken(userId, nickName, headAdress);
		RongYunDto rongYunDto = JsonUtil.json2Obj(RongYunToken, RongYunDto.class);
		vo.setRongYunToken(rongYunDto.getToken());
		return vo;
	}

	/**
	 * 用户退出登录
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void logout(UserInfoDto userInfoDto) {
		UserInfoEnity usertokenInfo = new UserInfoEnity();
		usertokenInfo.setId(userInfoDto.getId());
		usertokenInfo.setUpdTime(new Date());
		int line = userInfoDao.logout(usertokenInfo);
		LOGGER.info("----user----logout----------" + line);

	}

	// 首先判断用户是否存在；再判断用户账号状态是否可用；最后修改密码
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void forgetPassword(ForgetPasswordDto forgetPasswordDto) {
		UserInfoEnity userInfo = new UserInfoEnity();
		userInfo.setId(forgetPasswordDto.getId());
		userInfo.setIs_register(1);
		List<UserInfoEnity> isRegist = userInfoDao.select(userInfo);
		if (CollectionUtils.isEmpty(isRegist)) {
			throw new BusinessException(ResponseCode.ERROR, "用户不存在!");
		}

		if (!CollectionUtils.isEmpty(isRegist)) {
			UserInfoEnity user = isRegist.get(0);
			Integer userStatus = user.getUsrStatus();
			if (!userStatus.equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
				throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
			}
			userInfo.setUsrPassword(MD5Util.MD5(forgetPasswordDto.getPassword().trim()));
			userInfo.setUpdTime(new Date());
			int line = userInfoDao.update(userInfo);
			LOGGER.info("----user----forgetPassword----------" + line);
		}
	}

	// 验证顺序： 用户是否存在、用户状态是否正常、用户原密码是否正确
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void passwordUpdate(PasswordUpdateDto passwordUpdateDto) {
		UserInfoEnity userInfo = new UserInfoEnity();
		userInfo.setId(passwordUpdateDto.getId());
		userInfo.setIs_register(1);
		List<UserInfoEnity> isRegist = userInfoDao.select(userInfo);
		if (CollectionUtils.isEmpty(isRegist)) {
			throw new BusinessException(ResponseCode.ERROR, "用户不存在!");
		}

		UserInfoEnity user = isRegist.get(0);
		Integer userStatus = user.getUsrStatus();
		if (!userStatus.equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
			throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
		}
		if (!user.getUsrPassword().equals(MD5Util.MD5(passwordUpdateDto.getOldPassword().trim()))) {
			throw new BusinessException(ResponseCode.ERROR, "原密码错误!");
		}

		userInfo.setUsrPassword(MD5Util.MD5(passwordUpdateDto.getPassword().trim()));
		userInfo.setUpdTime(new Date());
		int line = userInfoDao.update(userInfo);
		LOGGER.info("----user----passwordUpdate----------" + line);
	}

	// 用户信息
	@Override
	public UserInfoVo userInfo(UserInfoDto userInfoDto) {
		UserInfoEnity userInfo = new UserInfoEnity();
		userInfo.setId(userInfoDto.getId());
		userInfo.setSex(null);
		userInfo.setIs_register(1);
		List<UserInfoEnity> isRegist = userInfoDao.select(userInfo);
		if (CollectionUtils.isEmpty(isRegist)) {
			throw new BusinessException(ResponseCode.ERROR, "用户不存在!");
		}

		UserInfoEnity user = isRegist.get(0);
		Integer userStatus = user.getUsrStatus();
		if (!userStatus.equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
			throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
		}

		UserInfoVo vo = new UserInfoVo();
		vo.setId(user.getId());
		vo.setUserLogo(user.getUserLogo());
		vo.setNickname(user.getNickname());
		if (user.getSex() == null) {
			vo.setSex(JianBaEnum.SexEnum.FEMALE.getValue());
		} else {
			vo.setSex(user.getSex());
		}
		if (user.getBirthday() != null) {
			vo.setBirthday(DateUtil.format(user.getBirthday(), DateUtil.DATE_FORMAT));
			vo.setAge(DateUtil.getAge(user.getBirthday()));
			vo.setConstellation(DateUtil.getConstellation(user.getBirthday()));
		} else {
			vo.setBirthday("1991-01-01");
			Date bir = DateUtil.parse("1991-01-01");
			vo.setAge(DateUtil.getAge(bir));
			vo.setConstellation(DateUtil.getConstellation(bir));
		}

		UserSignEnity userSign = userSignDao.selectByUserId(user.getId());
		if (userSign != null) {
			vo.setUserSign(userSign.getSignvalue());
		}
		List<LableTreeDto> lableTree = lableService.UserlableTree(user.getId());
		vo.setLableList(lableTree);

		int isFocus = 0;
		int isBlack = 0;
		if (userInfoDto.getRelationId() != null) {
			UserRelationEntity entity = new UserRelationEntity();
			entity.setUserId(userInfoDto.getRelationId());
			entity.setRelationId(userInfoDto.getId());
			List<UserRelationEntity> entityList = userRelationDao.select(entity);
			if (!CollectionUtils.isEmpty(entityList) && entityList.size() != 0) {
				if ("1".equals(entityList.get(0).getRelation())) {
					isFocus = 1;
				}
				if(("0").equals(entityList.get(0).getRelation())){
					isBlack = 1;
				}
			}
		}
		vo.setIsFocus(isFocus);
		vo.setIsBlack(isBlack);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userInfoDto.getId());
		map.put("mType", "personEditer");
		List<UserMessageVo> list = userMediaDao.findAddressListByMtypeAndUserId(map);
		list.stream().forEach(userMessageVo ->{
			if(!"0".equals(userMessageVo.getUrlType())&&StringUtils.isBlank(userMessageVo.getImgStr())){
				userMessageVo.setImgStr(imgStr);
			}
		});
		vo.setUserMessageList(list);
		return vo;

	}

	/**
	 * 注册后个人资料编辑
	 * @throws Exception 
	 *
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, Object> updateUserInfo(UserInfoVo userInfoVo) throws Exception {
		UserInfoEnity userInfo = userInfoDao.findById(userInfoVo.getId());

		if (userInfo == null) {
			throw new BusinessException(ResponseCode.ERROR, "用户不存在!");
		}
		if (!userInfo.getUsrStatus().equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
			throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
		}
		UserInfoEnity user = new UserInfoEnity();

		user.setId(userInfoVo.getId());
		user.setUserLogo(userInfoVo.getUserLogo());
		user.setNickname(userInfoVo.getNickname());
		user.setSex(userInfoVo.getSex());
		user.setBirthday(DateUtil.parse(DateUtil.DATE_FORMAT, userInfoVo.getBirthday()));
		user.setUpdTime(new Date());
		int line = userInfoDao.update(user);
		LOGGER.info("----userInfoDao----update----------" + line);

		List<LableTreeDto> userLabeListDto = userInfoVo.getLableList();

		List<UserLableEnity> lableList = new ArrayList<UserLableEnity>();
		if (!CollectionUtils.isEmpty(userLabeListDto)) {

			for (LableTreeDto dto : userLabeListDto) {

				UserLableEnity lable = new UserLableEnity();
				lable.setId(userInfoVo.getId());
				lable.setLable1Id(dto.getLableId());
				lable.setLable1Name(dto.getLableName());

				if (!CollectionUtils.isEmpty(dto.getChild())) {
					for (LableTreeDto secondto : dto.getChild()) {
						UserLableEnity secondLable = new UserLableEnity();
						secondLable.setId(userInfoVo.getId());
						secondLable.setLable1Id(dto.getLableId());
						secondLable.setLable1Name(dto.getLableName());
						secondLable.setLable2Id(secondto.getLableId());
						secondLable.setLable2Name(secondto.getLableName());
						lableList.add(secondLable);
					}
				} else {
					lableList.add(lable);
				}

			}
		}

		// 如果有标签则先删除之前的旧标签，再插入新的标签
		if (!CollectionUtils.isEmpty(lableList)) {
			int deleteLine = userLableDao.deleteByUserId(userInfoVo.getId());
			LOGGER.info("----userLableDao----deleteByUserId----------" + deleteLine);
			int batchLine = userLableDao.insertBatch(lableList);
			LOGGER.info("----userLableDao----insertBatch----------" + batchLine);
		}

		// 如果个性签名存在，先删除再插入
		if (StringUtils.isNotBlank(userInfoVo.getUserSign())) {
			int deleteLine = userSignDao.deleteByUserId(userInfoVo.getId());
			LOGGER.info("---------userSignDao.deleteByUserId------------" + deleteLine);
			UserSignEnity userSign = new UserSignEnity();
			userSign.setId(userInfoVo.getId());
			userSign.setSignvalue(userInfoVo.getUserSign());
			int signLine = userSignDao.insert(userSign);
			LOGGER.info("---------userSignDao.insert------------" + signLine);
		}

		//更新融云用户信息
		//		RongYunUtil.updateRongYunToken(String.valueOf(userInfoVo.getId()), userInfo.getNickname(), userInfo.getUserLogo());
		return null;
	}

	/**
	 * 注册时用户信息完善
	 * @throws Exception 
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, Object> consummationData(DetailedUserInfoDto detailedUserInfoDto) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();

		UserInfoEnity userInfo = userInfoDao.findById(detailedUserInfoDto.getId());

		if (userInfo == null) {
			throw new BusinessException(ResponseCode.ERROR, "用户不存在!");
		}
		if (!userInfo.getUsrStatus().equals(JianBaEnum.UserStatusEnum.NORMAL.getValue())) {
			throw new BusinessException(ResponseCode.ERROR, "账号状态异常，请联系管理员!");
		}
		userInfo.setNickname(detailedUserInfoDto.getNickname());
		Integer sex = detailedUserInfoDto.getSex();
		userInfo.setSex(sex);

		userInfo.setBirthday(detailedUserInfoDto.getBirthday());
		userInfo.setUpdTime(new Date());
		String userLogo = detailedUserInfoDto.getUserLogo();
		if (userLogo == null || userLogo.equals("")) {
			if (sex == 0) {
				userLogo = male;
			} else {
				userLogo = female;
			}
		}
		userInfo.setUserLogo(userLogo);

		int line = userInfoDao.update(userInfo);
		//更新成注册成功状态
		userInfoDao.updateIsregister(detailedUserInfoDto.getId());

		List<FirstLocationEnity> firstLocationList = new ArrayList<FirstLocationEnity>();
		if (!CollectionUtils.isEmpty(detailedUserInfoDto.getLocation())) {
			for (RegisterLocationVo location : detailedUserInfoDto.getLocation()) {

				LOGGER.info("----userInfoDao----update----------" + line);
				// 如果有经纬度信息
				if (location.getLatfloat() != null && location.getLngfloat() != null) {

					FirstLocationEnity firstLocationEnity = new FirstLocationEnity();

					LOGGER.info("-------UserLocation-----geom--------" + location.getGeom());
					firstLocationEnity.setId(detailedUserInfoDto.getId());
					firstLocationEnity.setLatfloat(location.getLatfloat());
					firstLocationEnity.setLngfloat(location.getLngfloat());
					firstLocationEnity.setGeom(location.getGeom());
					firstLocationList.add(firstLocationEnity);

				}
			}
			if (!CollectionUtils.isEmpty(firstLocationList)) {

				firstLocationDao.insertBatch(firstLocationList);
				// 第一次遇见
				procedureService.calFirstMeet(detailedUserInfoDto.getId());
			}
		}
		String RongYunToken = RongYunUtil.getRongYunToken(String.valueOf(userInfo.getId()), userInfo.getNickname(), userLogo);
		RongYunDto rongYunDto = JsonUtil.json2Obj(RongYunToken, RongYunDto.class);
		map.put("RongYunToken", rongYunDto.getToken());
		map.put("userLogo", userLogo);
		map.put("id", detailedUserInfoDto.getId());
		map.put("nickname", detailedUserInfoDto.getNickname());
		map.put("sex", sex);
		map.put("meetType", userInfo.getMeetType()==null?"0":(userInfo.getMeetType()+""));
		return map;
	}

	/**
	 * 获取用戶首页信息
	 */
	@Override
	public Page<IndexInfoDto> selectIndexInfoById(IndexDto indexDto) {

		Integer count = 0;
		List<IndexInfoDto> indexInfoList = new ArrayList<IndexInfoDto>();
		if (indexDto.getMeetType() != null) {
			if (indexDto.getMeetType() == 0) {
				indexDto.setMeetSex(new Integer[]{JianBaEnum.SexEnum.MALE.getValue(),JianBaEnum.SexEnum.FEMALE.getValue()});
			} else if (indexDto.getMeetType() == 1) {
				indexDto.setMeetSex(new Integer[]{JianBaEnum.SexEnum.MALE.getValue()});
				//只看女
			} else if (indexDto.getMeetType() == 2) {
				indexDto.setMeetSex(new Integer[]{JianBaEnum.SexEnum.FEMALE.getValue()});
			}else{
				indexDto.setMeetSex(new Integer[]{JianBaEnum.SexEnum.MALE.getValue(),JianBaEnum.SexEnum.FEMALE.getValue()});
			}
		} else {
			indexDto.setMeetSex(new Integer[]{JianBaEnum.SexEnum.MALE.getValue(),JianBaEnum.SexEnum.FEMALE.getValue()});
		}
		
		// 0：擦肩；
		if (indexDto.getType() == 0) {
			count = meetTme(indexDto, indexInfoList);
			if (count==null||count.equals(0)) {
				procedureService.IND_MEET_MATCH(indexDto.getId());
				count = meetTme(indexDto, indexInfoList);
			}
			// 1：同行；
		} else if (indexDto.getType() == 1) {
			count = meetDistance(indexDto, indexInfoList);
			if (count == null||count.equals(0)) {
				procedureService.IND_MEET_MATCH(indexDto.getId());
				count = meetDistance(indexDto, indexInfoList);
			}
			// 2:共度；
		} else if (indexDto.getType() == 2) {
			count = meetDuration(indexDto, indexInfoList);
			if (count == null||count.equals(0)) {
				procedureService.IND_MEET_MATCH(indexDto.getId());
				count = meetDistance(indexDto, indexInfoList);
			}
			// 3：身边 要用redis实时算的，不放数据库里
		} else if (indexDto.getType() == 3) {
			if (indexDto.getLngfloat() == null || indexDto.getLatfloat() == null) {
				throw new BusinessException(ResponseCode.ERROR, "经纬度不能为空!");
			}

			GeoResult geoResult = IniteDistance(indexDto);
			if (geoResult != null) {
				LOGGER.info("----userInfoDao----update----------" + JsonUtil.getJsonString(geoResult));
				// 身边
				count = meetNearBy(indexDto, geoResult, indexInfoList);
			}
		}
		//当真数据小于10条时，补充假数据
		count = addFake(indexDto, count, indexInfoList);
		
		//设置是否关注
		for (IndexInfoDto indexInfoDto : indexInfoList) {
			int isFocus = 0;
			if (indexInfoDto.getMatchUserId() != null) {
				UserRelationEntity entity = new UserRelationEntity();
				entity.setUserId(indexInfoDto.getId());
				entity.setRelationId(indexInfoDto.getMatchUserId());
				List<UserRelationEntity> entityList = userRelationDao.select(entity);
				if (!CollectionUtils.isEmpty(entityList) && entityList.size() != 0) {
					if ("1".equals(entityList.get(0).getRelation())) {
						isFocus = 1;
					}
				}
			}
			indexInfoDto.setIsFocus(isFocus);
		}

		// 首页设置默认值
		setDefaultValue(indexDto, indexInfoList);
		LOGGER.info("-----index-count-------" + count);
		
		Pageable pageable = new Pageable(indexDto.getPageNumber(), indexDto.getPageSize());
		Page<IndexInfoDto> pageVo = new Page<IndexInfoDto>(indexInfoList, count, pageable);

		return pageVo;
	}

	
	/**
	 * 填充假数据,直到假数据没有为止
	 * @param indexDto
	 * @param count
	 * @param indexInfoList
	 * @return
	 */
	public Integer addFake(IndexDto indexDto, Integer count, List<IndexInfoDto> indexInfoList) {
		int existcount;//能请求的最大数据总量,即数据库存在的总量
		int fakecount;//假数据条数
		int fakeoffset;//假数据偏移量
		int fakesize;//取多少假数据
		if(indexDto.getMeetSex().length==1){
			fakecount=25;
			existcount=fakecount+count;//count为真实数据总量
		}else{
			fakecount=50;
			existcount=fakecount+count;
		}
		//当请求某页数据时,该页实际返回数量小于请求数量时,用假数据补上
		int needCount=indexDto.getPageNumber()*indexDto.getPageSize();//数据库里需要存在的数据总量
		int precount=needCount-indexDto.getPageSize();//上一次请求需要的数据总量
		int prepageNumber=indexDto.getPageNumber()-1;//上一次请求的页码
		if(count<needCount&&precount<existcount&&count<10){
			if(needCount<=existcount){
				if(needCount-indexDto.getPageSize()>count){
					fakeoffset=needCount-count-indexDto.getPageSize();//startId=138+fakeoffset
					fakesize=indexDto.getPageSize();
				}else{
					fakeoffset=0;//startId=138+0
					fakesize=needCount-count;
				}
			}else{
				fakeoffset=precount-count;//startId=138+fakeoffset;
				fakesize=existcount-precount;
			}
			count=matchFake(indexDto, indexInfoList,fakeoffset,fakesize)+count;
		}
		return count;
	}

	/**
	 * 用户距离
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private GeoResult IniteDistance(IndexDto indexDto) {

		String db = null;
		//性别类型:性别： 0:男；1：女;null：男女
		Integer sex = null;
		//默认看男女
		if (indexDto.getMeetType() != null) {
			if (indexDto.getMeetType() == 0) {
				db = meetDb;
			} else if (indexDto.getMeetType() == 1) {
				db = maleMeetDb;
				sex = JianBaEnum.SexEnum.MALE.getValue();
				//只看女
			} else if (indexDto.getMeetType() == 2) {
				db = femaleMeetDb;
				sex = JianBaEnum.SexEnum.FEMALE.getValue();
			}
		} else {
			db = meetDb;
		}
		// 缓存初始化
		initeCache(indexDto, db, sex);

		GeoResults<GeoLocation<String>> geoResults = redisService.radiusGeo(db, indexDto.getLngfloat().doubleValue(), indexDto
				.getLatfloat().doubleValue(), nearDistance, nearCount, DistanceUnit.METERS);
		if (geoResults != null) {
			GeoResult geoResult = JsonUtil.json2Obj(JsonUtil.getJsonString(geoResults), GeoResult.class);
			return geoResult;
		}
		return null;
	}

	/**
	 * 缓存初始化
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private void initeCache(IndexDto indexDto, String db, Integer sex) {

		Long count = null;

		//如果是只看男 或者只看女
		if (db != null) {
			count = redisService.count(db);
			if (count == null || count == 0) {
				UserInfoEnity userInfo = new UserInfoEnity();
				userInfo.setSex(sex);
				userInfo.setIs_register(1);
				List<UserInfoEnity> userList = userInfoDao.select(userInfo);
				Set<String> idSet = new HashSet<String>();
				//性别map key=userId ,value=sex
				Map<String, Integer> sexMap = new HashMap<String, Integer>();
				if (!CollectionUtils.isEmpty(userList) && userList.size() > 0) {
					userList.stream().forEach(user -> {
						sexMap.put(user.getId() + "", user.getSex());
						idSet.add(user.getId() + "");
					});
				}
				List<UserLocationEnity> allList = userLocationHDao.findAll();
				if (!CollectionUtils.isEmpty(allList) && allList.size() > 0) {
					for (UserLocationEnity userLocal : allList) {
						if (idSet.contains(userLocal.getId())) {
							//只设置男或者女缓存数据
							Integer userSex = sexMap.get(userLocal.getId());
							//如果性别 为空；则是设置通用缓存数据
							if (sex == null) {
								redisService.geoadd(meetDb, userLocal.getId(), userLocal.getLngfloat().doubleValue(), userLocal.getLatfloat()
										.doubleValue());
								//如果性别 不为空；则是设置男或女缓存数据
							} else if (sex.equals(userSex)) {
								redisService.geoadd(db, userLocal.getId(), userLocal.getLngfloat().doubleValue(), userLocal.getLatfloat()
										.doubleValue());

							}
						}
					}
				}
			}
		}

	}

	/**
	 * 身边
	 * 
	 * @param indexInfoList
	 * @param geoResult
	 */
	private Integer meetNearBy(IndexDto indexDto, GeoResult geoResult, List<IndexInfoDto> indexInfoList) {
		Integer count = 0;
		List<Long> idList = new ArrayList<Long>();
		List<Results> totalList = new ArrayList<Results>();

		geoResult.getResults().stream().forEach(result -> {
			// 排除用户自己
				if (StringUtils.isNotBlank(result.getContent().getName())) {
					long id = Long.parseLong(result.getContent().getName());
					if (id != indexDto.getId().longValue()) {
						idList.add(id);
						totalList.add(result);
					}
				}
			});
		LOGGER.info("---meetNearBy---idList-------" + idList);
		if (idList.size() > 0) {
			List<Results> resultList = new ArrayList<Results>();
			//分页
			getPage(totalList, indexDto, count, resultList);
			// key =userId ,value= nickName
			Map<String, String> nickNameMap = new HashMap<String, String>();
			nickNameMap = assembleNickName(idList);
			for (Results res : resultList) {
				long id = Long.parseLong(res.getContent().getName());
				if (id != indexDto.getId().longValue()) {
					IndexInfoDto indexInfoDto = new IndexInfoDto();
					indexInfoDto.setId(indexDto.getId());
					indexInfoDto.setType(indexDto.getType());
					indexInfoDto.setMatchUserId(id);
					indexInfoDto.setTime(res.getDistance().getValue() + "");
					if(res.getDistance().getValue()<100){//小于一百米则提示
						indexInfoDto.setIsNear(String.valueOf(1));
					}else{
						indexInfoDto.setIsNear(String.valueOf(0));
					}
					if (nickNameMap != null) {
						indexInfoDto.setMatchUserName(nickNameMap.get(res.getContent().getName()));
					}
					List<UserMessageVo> list = this.findAddressListByMtypeAndUserId(Long.parseLong(res.getContent().getName()));
					indexInfoDto.setUserMessageList(list);
					indexInfoList.add(indexInfoDto);
				}
			}

			count = idList.size();
		}

		return count;
	}

	private void getPage(List<Results> results, IndexDto indexDto, Integer count, List<Results> resultList) {
		if (!CollectionUtils.isEmpty(results) && results.size() > 0) {
			int totalCount = results.size();
			int startIndex = (indexDto.getPageNumber() - 1) * indexDto.getPageSize() + 1;
			int endIndex = indexDto.getPageNumber() * indexDto.getPageSize();
			endIndex = endIndex > totalCount ? totalCount : endIndex;
			if (startIndex <= endIndex && startIndex != 0) {
				for (int i = startIndex; i <= endIndex; i++) {
					resultList.add(results.get(i - 1));
				}
			}
			count = totalCount;
		}

	}
	/**
	 * 首页设置默认值
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private void setDefaultValue(IndexDto indexDto, List<IndexInfoDto> indexInfoList) {
		for (IndexInfoDto indexInfoDto : indexInfoList) {
			UserInfoEnity userInfo = userInfoDao.findById(indexInfoDto.getMatchUserId());
			if (userInfo != null) {
				if (StringUtils.isBlank(userInfo.getNickname())) {
					if (userInfo.getSex() != null && userInfo.getSex().intValue() == 0) {
						indexInfoDto.setMatchUserName("帅哥");
					} else {
						indexInfoDto.setMatchUserName("美女");
					}
				} else {
					indexInfoDto.setMatchUserName(userInfo.getNickname());
				}

				indexInfoDto.setMatchUserLogo(userInfo.getUserLogo());
				UserSignEnity userSignEnity = userSignDao.selectByUserId(indexInfoDto.getMatchUserId());
				if (userSignEnity != null) {
					indexInfoDto.setUserSign(userSignEnity.getSignvalue());
				} else {
					indexInfoDto.setUserSign("");
				}

				if (userInfo.getBirthday() == null) {
					Date bir = DateUtil.parse("1991-01-01");
					indexInfoDto.setAge(DateUtil.getAge(bir));
					indexInfoDto.setConstellation(DateUtil.getConstellation(bir));
				} else {
					indexInfoDto.setConstellation(DateUtil.getConstellation(userInfo.getBirthday()));
					indexInfoDto.setAge(DateUtil.getAge(userInfo.getBirthday()));
				}
				if (userInfo.getSex() == null) {
					indexInfoDto.setSex(JianBaEnum.SexEnum.FEMALE.getValue());
				} else {
					indexInfoDto.setSex(userInfo.getSex());
				}
//				List<LableTreeDto> lableTree = lableService.UserlableTree(indexDto.getId());
//				indexInfoDto.setLableList(lableTree);

			}
		}
	}

	/**
	 * 共度
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private Integer meetDuration(IndexDto indexDto, List<IndexInfoDto> indexInfoList) {
		Integer count;
		List<MeetDuraEnity> duraList = meetDuraDao.findPage(indexDto);
		if (!CollectionUtils.isEmpty(duraList)) {
			List<Long> idList = new ArrayList<Long>();

			duraList.stream().forEach(dura -> idList.add(Long.parseLong(dura.getMatchId())));

			// key =userId ,value= nickName
			Map<String, String> nickNameMap = new HashMap<String, String>();
			nickNameMap = assembleNickName(idList);

			for (MeetDuraEnity meetDuraEnity : duraList) {
				IndexInfoDto indexInfoDto = new IndexInfoDto();
				indexInfoDto.setId(indexDto.getId());
				indexInfoDto.setType(indexDto.getType());
				indexInfoDto.setIsNear(String.valueOf(meetDuraEnity.getIsNear()));
				indexInfoDto.setMatchUserId(Long.parseLong(meetDuraEnity.getMatchId()));
				indexInfoDto.setTime(meetDuraEnity.getDuration() + "");
				if (nickNameMap != null) {
					indexInfoDto.setMatchUserName(nickNameMap.get(meetDuraEnity.getMatchId()));
				}
				List<UserMessageVo> list = this.findAddressListByMtypeAndUserId(Long.parseLong(meetDuraEnity.getMatchId()));
				indexInfoDto.setUserMessageList(list);
				indexInfoList.add(indexInfoDto);
			}

		}

		count = meetDuraDao.findPageCount(indexDto);
		return count;
	}

	/**
	 * 同行
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private Integer meetDistance(IndexDto indexDto, List<IndexInfoDto> indexInfoList) {
		Integer count;
		List<MeetDistanceEnity> meetList = meetDistanceDao.findPage(indexDto);
		if (!CollectionUtils.isEmpty(meetList)) {
			List<Long> idList = new ArrayList<Long>();

			meetList.stream().forEach(meet -> idList.add(Long.parseLong(meet.getMatchId())));

			// key =userId ,value= nickName
			Map<String, String> nickNameMap = new HashMap<String, String>();
			nickNameMap = assembleNickName(idList);

			for (MeetDistanceEnity meetDistanceEnity : meetList) {
				IndexInfoDto indexInfoDto = new IndexInfoDto();
				indexInfoDto.setId(indexDto.getId());
				indexInfoDto.setType(indexDto.getType());
				indexInfoDto.setIsNear(String.valueOf(meetDistanceEnity.getIsNear()));
				indexInfoDto.setMatchUserId(Long.parseLong(meetDistanceEnity.getMatchId()));
				indexInfoDto.setTime(meetDistanceEnity.getDistance() + "");
				if (nickNameMap != null) {
					indexInfoDto.setMatchUserName(nickNameMap.get(meetDistanceEnity.getMatchId()));
				}
				List<UserMessageVo> list = this.findAddressListByMtypeAndUserId(Long.parseLong(meetDistanceEnity.getMatchId()));
				indexInfoDto.setUserMessageList(list);
				indexInfoList.add(indexInfoDto);
			}
		}
		count = meetDistanceDao.findPageCount(indexDto);
		return count;
	}

	/**
	 * 擦肩
	 *
	 * @author liuhaitao
	 * @param
	 * @return
	 * @exception
	 * @since JDK 1.8
	 */
	private Integer meetTme(IndexDto indexDto, List<IndexInfoDto> indexInfoList) {
		Integer count;
		List<MeetTimeEnity> timeList = meetTimeDao.findPage(indexDto);
		if (!CollectionUtils.isEmpty(timeList)) {

			timeList.stream().forEach(meetTimeEnity -> {
				IndexInfoDto indexInfoDto = new IndexInfoDto();
				indexInfoDto.setId(indexDto.getId());
				indexInfoDto.setType(indexDto.getType());
				indexInfoDto.setMatchUserId(Long.parseLong(meetTimeEnity.getMatchId()));
				indexInfoDto.setTime(meetTimeEnity.getMeettime() + "");
				indexInfoDto.setIsNear(String.valueOf(meetTimeEnity.getIsNear()));
				List<UserMessageVo> list = this.findAddressListByMtypeAndUserId(Long.parseLong(meetTimeEnity.getMatchId()));
				indexInfoDto.setUserMessageList(list);
				indexInfoList.add(indexInfoDto);
			});

		}

		count = meetTimeDao.findPageCount(indexDto);
		return count;
	}
	
	/**
	 * 匹配人数不够时,补上假数据,直到假数据补完为止
	 * @param indexDto
	 * @param indexInfoList
	 * @return
	 */
	private Integer matchFake(IndexDto indexDto, List<IndexInfoDto> indexInfoList,int fakeoffset,int fakesize){
		Map<String,Long> map=new HashMap<String,Long>();
		Integer[] meetSex=indexDto.getMeetSex();
		Long femaleStartId=null;
		Long maleStartId=null;
		Long endId=null;
		List<UserInfoEnity> listRe=null;
		List<UserInfoEnity> maleList=null;
		List<UserInfoEnity> femaleList=null;
		if(indexDto.getType() == 0){//擦肩
			femaleStartId=138l;
			maleStartId=238l;
		}else if(indexDto.getType() == 1){//同行
			femaleStartId=163l;//138+25
			maleStartId=263l;
		}else{//身边
			femaleStartId=188l;//138+50
			maleStartId=288l;
		}
		if(meetSex.length==2){//男女
			
			if(fakeoffset+fakesize<=25){
				//女
				map.put("startId", femaleStartId+fakeoffset);
				map.put("endId", femaleStartId+fakeoffset+fakesize-1);
				femaleList=userInfoDao.findByUidBetween(map);
				listRe=femaleList;
			}else{
				if(fakeoffset<25){
					//女
					map.put("startId", femaleStartId+fakeoffset);
					map.put("endId", femaleStartId+25-1);
					femaleList=userInfoDao.findByUidBetween(map);
					//男
					map.put("startId", maleStartId);
					map.put("endId", maleStartId+fakesize-(25-fakeoffset)-1);
					maleList=userInfoDao.findByUidBetween(map);
					femaleList.addAll(maleList);
					listRe=femaleList;
				}
			}
			
		}else if(meetSex[0]==JianBaEnum.SexEnum.MALE.getValue()){
			//男
			map.put("startId", maleStartId+fakeoffset);
			map.put("endId", maleStartId+fakeoffset+fakesize-1);
			maleList=userInfoDao.findByUidBetween(map);
			listRe=maleList;
		}else {
			//女
			map.put("startId", femaleStartId+fakeoffset);
			map.put("endId", femaleStartId+fakeoffset+fakesize-1);
			femaleList=userInfoDao.findByUidBetween(map);
			listRe=femaleList;
		}
		if (!CollectionUtils.isEmpty(listRe)) {
			listRe.stream().forEach(meetTimeEnity -> {
				IndexInfoDto indexInfoDto = new IndexInfoDto();
				indexInfoDto.setId(indexDto.getId());
				indexInfoDto.setType(indexDto.getType());
				indexInfoDto.setMatchUserId(meetTimeEnity.getId());
				indexInfoDto.setTime("1");
				indexInfoDto.setIsNear("0");
				List<UserMessageVo> list = this.findAddressListByMtypeAndUserId(meetTimeEnity.getId());
				indexInfoDto.setUserMessageList(list);
				indexInfoList.add(indexInfoDto);
			});

		}
		return meetSex.length==2?50:25;
	}

	private Map<String, String> assembleNickName(List<Long> idList) {
		Map<String, String> nickNameMap = new HashMap<String, String>();
		List<UserInfoEnity> resuList = findBatchByUserIdList(idList);
		if (!CollectionUtils.isEmpty(resuList) && resuList.size() > 0) {
			resuList.stream().forEach(userInfo -> {
				nickNameMap.put(userInfo.getId() + "", userInfo.getNickname());
			});
		}
		return nickNameMap;
	}

	/**
	 * 批量查询用户
	 * 
	 * @param idList
	 * @return
	 */
	private List<UserInfoEnity> findBatchByUserIdList(List<Long> idList) {
		List<UserInfoEnity> resuList = new ArrayList<UserInfoEnity>();
		if (!CollectionUtils.isEmpty(idList)) {
			List<List<Long>> listLists = ListUtil.splitList(idList, Constants.CUT_LIST_SIZE);
			listLists.stream().forEach(list -> {
				List<UserInfoEnity> userList = this.userInfoDao.findByUserIdList(list);
				if (!CollectionUtils.isEmpty(userList)) {
					resuList.addAll(userList);
				}
			});
		}
		return resuList;
	}

	// 根据用户id查询personEditer模块的照片或者是视频
	private List<UserMessageVo> findAddressListByMtypeAndUserId(Long userId) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userId);
		map.put("mType", "personEditer");
		List<UserMessageVo> list = userMediaDao.findAddressListByMtypeAndUserId(map);
		list.stream().forEach(userMessageVo ->{
			if(StringUtils.isBlank(userMessageVo.getImgStr())){
				userMessageVo.setImgStr(this.imgStr);
			}else if("1".equals(userMessageVo.getImgStr())){
				userMessageVo.setImgStr("");
			}
		});
		return list;
	}

	@Override
	public LoginVo getInfoByUserId(String userId) {
		UserInfoEnity userInfoEnity = new UserInfoEnity();
		userInfoEnity.setId(Long.parseLong(userId));
		userInfoEnity.setIs_register(1);
		List<UserInfoEnity> list = userInfoDao.select(userInfoEnity);
		UserInfoEnity info = list.get(0);
		LoginVo loginVo = null;
		if (info != null) {
			loginVo = new LoginVo();
			loginVo.setId(info.getId());
			loginVo.setNickname(info.getNickname());
			loginVo.setSex(info.getSex());
			loginVo.setUserLogo(info.getUserLogo());
		}
		return loginVo;
	}

	@Override
	public int sexChoose(Long userId, Integer sex) {
		int re;
		UserInfoEnity userInfoEnity=new UserInfoEnity();
		if(sex.equals(0)||sex.equals(1)||sex.equals(2)){
		userInfoEnity.setId(userId);
		userInfoEnity.setMeetType(sex);
		re=userInfoDao.update(userInfoEnity);
		}else{
			throw new BusinessException(ResponseCode.BAD_REQUEST, "请求不合法");
		}
		return re;
		
	}

	@Override
	public LoginVo getBuziInfoByUserId(String userId) {
		BuziInfoEntity buziInfoEntity=new BuziInfoEntity();
		buziInfoEntity.setId(Long.parseLong(userId));
		List<BuziInfoEntity> list=buziInfoDao.select(buziInfoEntity);
		if(CollectionUtils.isEmpty(list)){
			throw new BusinessException(ResponseCode.ERROR, "该商家id不存在");
		}
		BuziInfoEntity buziInfo=list.get(0);
		LoginVo loginVo=new LoginVo();
		if (buziInfo != null) {
			loginVo = new LoginVo();
			loginVo.setId(buziInfo.getId());
			loginVo.setNickname(buziInfo.getName()==null?buziname:buziInfo.getName());
			loginVo.setSex(3);
			loginVo.setUserLogo(buziInfo.getLogo()==null?buziLogo:buziInfo.getLogo());
		}
		
		return loginVo;
	}

}
